/**
 * 服务
 * */
package org.zmhhxl.sample3.oauth2.a.mapper;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.core.oidc.OidcUserInfo;
import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcUserInfoAuthenticationContext;
import org.zmhhxl.sample3.oauth2.a.service.CustomOidcUserInfoService;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

/**
 * 全部都会调用，不论什么方式登录
 * 主要是输出用户信息，在jwt token中不会包含
 * 适用于在用户信息请求处理完成后，需要对用户信息进行进一步处理和映射的场景
 * */
@Slf4j
public class CustomUserInfoMapper implements Function<OidcUserInfoAuthenticationContext, OidcUserInfo> {

//   @Autowired
//   private UserDetailsService userDetailsService;   // CustomUserDetailsService

   @Autowired
   private CustomOidcUserInfoService customOidcUserInfoService; //= new CustomOidcUserInfoService();

//   @Autowired
//   private Oauth2UserConverterContext oauth2UserConverterContext;

   /**
    * 信息重新转换组合，然后输出给请求
    * */
   @Override
   public OidcUserInfo apply(OidcUserInfoAuthenticationContext context) {
      // 获取默认的OidcUserInfo 实例不存在
      //OidcUserInfo oidcUserInfo = (OidcUserInfo) context.getAuthorization().getAttributes().get(OidcUserInfo.class); //.get(OidcUserInfo.class).orElseThrow()
      // 获取默认的用户信息
      // OidcUserInfo defaultUserInfo = (OidcUserInfo)context.getAuthentication().getPrincipal();
      log.info("hhhhh ======= 第三方登录成功后也会调用用户信息映射,每次访问userinfo端点时,都将调用此映射");
      //customOidcUserInfoService(context.getUserRequest())
      //OAuth2Authorization authorization = context.getAuthorization();

      //有2个对象，OAuth2AuthorizationRequest，和java.security.Principal(authorities,details,principal(userId,username,authorities,accountNonExpired,accountNonLocked,,,))

      // 获取认证上下文中的认证令牌
     // /*OidcUserInfoAuthenticationToken*/ JwtAuthenticationToken authentication = (JwtAuthenticationToken) context.getAuthentication();

      // 获取 JWT 令牌
      //Jwt jwt = authentication.getToken();

      // 获取原始的 OidcUser 对象
      //OidcUser originalUser = (OidcUser) authentication.getPrincipal();



//      OidcUserRequest oidcUserRequest = new OidcUserRequest(
//            Objects.requireNonNull(authorization.getAttribute(authorization.getRegisteredClientId())),
//            context.getAccessToken(),
//            ((org.springframework.security.oauth2.core.oidc.user.OidcUser) authorization.getAttribute(authorization.getPrincipalName())).getIdToken()
//      );
      // zmhhxl修改  OidcUserRequest  OidcUserService customOidcUserInfoService
      //OidcUser oidcUserInfo = customOidcUserInfoService.loadUser(oidcUserRequest);


      // 假设我们有一个服务可以提供额外的用户信息
      // 可以在这里添加自定义的用户信息
      Map<String, Object> additionalInfo = fetchAdditionalUserInfo(context);

      // 合并默认的UserInfo和额外信息
      Map<String, Object> mergedClaims = new HashMap<>(context.getAuthorization().getAttributes());  //oidcUserInfo.getClaims()
      mergedClaims.putAll(additionalInfo);

      // 创建新的 OidcUser 对象
      //OidcUser oidcUserInfo = new DefaultOidcUser(originalUser.getAuthorities(), originalUser.getIdToken(), mergedClaims);

      return  new OidcUserInfo(mergedClaims);
      // 返回新的OidcUserInfo实例，包含合并后的信息,在jwt token中不会包含
      //return OidcUserInfo(mergedClaims);
   }

   private Map<String, Object> fetchAdditionalUserInfo(OidcUserInfoAuthenticationContext context) {
      // 实现此方法以从数据库或其他服务获取额外的用户信息
      String username = context.getAuthorization().getPrincipalName(); // 或者其他方式获取用户名
      //return customOidcUserInfoService.loadUser(username);
      // 示例：返回一些硬编码的额外信息
      return Collections.singletonMap("zmhhxl自定义添加额外信息custom_attribute: ", username);
   }
}
